#include "AudioChannel.h"

#include <cstring>

AudioChannel::AudioChannel() {

}

AudioChannel::~AudioChannel() {
    //释放编码器
    faacEncClose(codec);
    codec = nullptr;
    //释放缓冲区
    DELETE(outputBuffer)
}

//设置音频编码信息
void AudioChannel::setAudioEncodeInfo(int sampleRate, int channels) {
    this->channels = channels;
    //打开FAAC音频编码器，得到输入输出缓冲区的大小
    //inputSamples是一次最大输入的样本数量，outputBytes是一次最大输出的字节数
    codec = faacEncOpen(sampleRate, channels, &inputSampleCount, &outputBufferSize);
    //设置编码器参数
    faacEncConfigurationPtr config = faacEncGetCurrentConfiguration(codec);
    config->mpegVersion = MPEG4;
    config->aacObjectType = LOW;
    config->inputFormat = FAAC_INPUT_16BIT;
    //0为AAC裸数据，1为ADTS头+AAC裸数据
    //RTMP推流时，需要先单独发送一个解码信息数据包，再继续发AAC裸数据，所以需要使用0格式
    config->outputFormat = 0;
    faacEncSetConfiguration(codec, config);
    //创建输出缓冲区
    outputBuffer = new u_char[outputBufferSize];
}

//获得解码时一次最大输入的样本数量
int AudioChannel::getInputSamples() {
    return inputSampleCount;
}

//生成存储AudioSpecificConfig的Packet
RTMPPacket *AudioChannel::createConfigPacket() {
    //创建AudioSpecificConfig
    u_char *buffer;
    u_long infoSize;
    faacEncGetDecoderSpecificInfo(codec, &buffer, &infoSize);
    int bodySize = 2 + infoSize;
    //创建RTMPPacket
    RTMPPacket *packet = new RTMPPacket;
    RTMPPacket_Alloc(packet, bodySize);
    //设置Header
    packet->m_packetType = RTMP_PACKET_TYPE_AUDIO;
    packet->m_headerType = RTMP_PACKET_SIZE_LARGE;
    packet->m_nBodySize = bodySize;
    packet->m_hasAbsTimestamp = 0;
    packet->m_nTimeStamp = RTMP_GetTime() - startTime;
    //给不同的数据类型分配一个通道号
    //可自由分配，但不能和rtmp.c中已使用的值重复
    //音视频的数据包通道号也不能一样，此项目中使用0x11表示音频，0x10表示视频
    packet->m_nChannel = 0x11; //通道号
    //填充AudioSpecificConfig到RTMPPacket
    packet->m_body[0] = channels == 1 ? 0xAE : 0xAF; //AudioInfo，由声道，位数，比特率，音频格式等信息经过位运算获得
    packet->m_body[1] = 0x00; //PacketType，0x00表示AAC头，0x01表示AAC裸数据
    memcpy(&packet->m_body[2], buffer, infoSize);
    return packet;
}

//编码AAC音频裸数据
RTMPPacket *AudioChannel::createRawDataPacket(int8_t *data) {
    //返回编码后数据字节的长度
    int dataSize = faacEncEncode(codec, reinterpret_cast<int32_t *>(data), inputSampleCount, outputBuffer, outputBufferSize);
    if (dataSize > 0) {
        int bodySize = 2 + dataSize;
        //创建RTMPPacket
        RTMPPacket *packet = new RTMPPacket;
        RTMPPacket_Alloc(packet, bodySize);
        //设置Header
        packet->m_packetType = RTMP_PACKET_TYPE_AUDIO;
        packet->m_headerType = RTMP_PACKET_SIZE_LARGE;
        packet->m_nBodySize = bodySize;
        packet->m_hasAbsTimestamp = 0;
        packet->m_nTimeStamp = RTMP_GetTime() - startTime;
        packet->m_nChannel = 0x11; //通道号
        //填充RawData到RTMPPacket
        packet->m_body[0] = channels == 1 ? 0xAE : 0xAF; //AudioInfo，由声道，位数，比特率，音频格式等信息经过位运算获得
        packet->m_body[1] = 0x01; //PacketType，0x00表示AAC头，0x01表示AAC裸数据
        memcpy(&packet->m_body[2], outputBuffer, dataSize);
        return packet;
    }
    return nullptr;
}

